/*
 * This file is part of ActivityInfo.
 *
 * ActivityInfo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ActivityInfo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ActivityInfo.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2009 Alex Bertram and contributors.
 */

using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.ArcMap;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Framework;

namespace ActivityInfo.ArcGIS.Tiles
{
    public partial class ExportTilesDialog : Form
    {
        #region class memebers
        private IHookHelper m_hookHelper = null;
        #endregion


        #region class constructor
        public ExportTilesDialog(IHookHelper hookHelper)
        {
            if (null == hookHelper)
                throw new Exception("Hook helper is not initialize");


            InitializeComponent();

            m_hookHelper = hookHelper;
            xMinTextBox.Text = "-180";
            xMaxTextBox.Text = "180";
            yMinTextBox.Text = "-90";
            yMaxTextBox.Text = "90";

            UpdateTileCount();
        }
        #endregion

        private int MinZoomLevel
        {
            get
            {
                if (fromZoomLevelUpDown.Value < toZoomLevelUpDown.Value)
                    return (int)fromZoomLevelUpDown.Value;
                else
                    return (int)toZoomLevelUpDown.Value;
            }
        }

        private int MaxZoomLevel
        {
            get
            {
                if (fromZoomLevelUpDown.Value > toZoomLevelUpDown.Value)
                    return (int)fromZoomLevelUpDown.Value;
                else
                    return (int)toZoomLevelUpDown.Value;
            }
        }

        private IEnvelope ParseBounds() 
        {
            IEnvelope bounds = new EnvelopeClass();
            bounds.XMin = Double.Parse(xMinTextBox.Text);
            bounds.XMax = Double.Parse(xMaxTextBox.Text);
            bounds.YMin = Double.Parse(yMinTextBox.Text);
            bounds.YMax = Double.Parse(yMaxTextBox.Text);
            return bounds;
        }

        private string composeName()
        {
            IApplication app = (IApplication)m_hookHelper.Hook;
            IDocumentInfo docInfo = (IDocumentInfo)app.Document;

            string name = docInfo.DocumentTitle;
            name = name.Replace(" ", "");

            char[] illegalCharacters = new char[] { '+', '-', '!', '/', '\\', '.', '^', '*', '&', '@', '%', '(', ')' };
            foreach (char c in illegalCharacters)
            {
                name = name.Replace(c, '_');
            }
            return name;
        }

        private void btnOK_Click(object sender, EventArgs evt)
        {
            if (outputFolderTextBox.Text.Length == 0)
            {
                MessageBox.Show("Please choose an output folder");
                return;
            }

            IEnvelope bounds = new EnvelopeClass();
            try {
                bounds = ParseBounds();  
            } catch(FormatException) {
                MessageBox.Show("Please enter valid coordinates for the bounds in DDd notation. For example: 63.23223 or -180");
                return;
            }

            ProgressDialog progressDialog = new ProgressDialog();
            progressDialog.Show(this);

            try
            {
                Exporter exporter = new Exporter(m_hookHelper.FocusMap);
                exporter.ExportTiles(
                    composeName(),
                    "",
                    MinZoomLevel,
                    MaxZoomLevel,
                    bounds,
                    outputFolderTextBox.Text, progressDialog);
            }
            catch (Exception e)
            {
                MessageBox.Show("Exception thrown while creating tiles: " + e.Message + "\n" + e.StackTrace);
                progressDialog.Close();
                return;
            }

            progressDialog.Hide();

            if (!progressDialog.isCancelled())
            {
            
                MessageBox.Show(this, "Export complete", "ArcTiles");
                this.Close();
            }
            progressDialog.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            if(folderBrowserDialog.ShowDialog() == DialogResult.OK) {
                outputFolderTextBox.Text = folderBrowserDialog.SelectedPath;
            }
        }

        private void fromZoomLevelUpDown_ValueChanged(object sender, EventArgs e)
        {
            UpdateTileCount();
        }


        private void toZoomLevelUpDown_ValueChanged(object sender, EventArgs e)
        {
            UpdateTileCount();
        }

        private void yMaxTextBox_TextChanged(object sender, EventArgs e)
        {
            UpdateTileCount();
        }

        private void xMinTextBox_TextChanged(object sender, EventArgs e)
        {
            UpdateTileCount();
        }

        private void xMaxTextBox_TextChanged(object sender, EventArgs e)
        {
            UpdateTileCount();
        }

        private void yMinTextBox_TextChanged(object sender, EventArgs e)
        {
            UpdateTileCount();
        }

        private void UpdateTileCount()
        {
            try {
                IEnvelope bounds = ParseBounds();

                Exporter exporter = new Exporter(m_hookHelper.FocusMap);
                int count = exporter.CountTiles(MinZoomLevel, MaxZoomLevel, ParseBounds());
                if (count == 1)
                    tileCountLabel.Text = "1 tile";
                else
                    tileCountLabel.Text = String.Format("{0:N} tiles", count);

            } catch(Exception) {
                tileCountLabel.Text = "";
            }
        }


    }
}